package com.wkg.lotterysystem.service.activitystatus.impl;

import com.wkg.lotterysystem.common.errorcode.ServiceErrorCodeConstants;
import com.wkg.lotterysystem.common.exception.ServiceException;
import com.wkg.lotterysystem.service.ActivityService;
import com.wkg.lotterysystem.service.dto.ConvertActivityStatusDTO;
import com.wkg.lotterysystem.service.activitystatus.ActivityStatusManager;
import com.wkg.lotterysystem.service.activitystatus.operater.AbstractActivityOperator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@Service
public class ActivityStatusManagerImpl implements ActivityStatusManager {

    private static final Logger log = LoggerFactory.getLogger(ActivityStatusManagerImpl.class);

    @Autowired
    private final Map<String, AbstractActivityOperator> operatorMap = new HashMap<>();
    @Autowired
    private ActivityService activityService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        //解决下面问题：
        // 1、活动状态扭转有依赖性，导致代码维护性差
        // 2.状态扭转体条件可能会扩展，当前写法，扩展性差，维护性差
        if (CollectionUtils.isEmpty(operatorMap)) {
            log.warn("operatorMap 为空！");
            return;
        }

        //map<String,AbstractActivityOperator>
        Map<String, AbstractActivityOperator> currMap = new HashMap<>(operatorMap);
        Boolean update = false;
        //先处理：人员、奖品
        update = processConvertStatus(convertActivityStatusDTO, currMap, 1);
        //后处理：活动
        update = processConvertStatus(convertActivityStatusDTO, currMap, 2) || update;

        //更新缓存
        if (update) {
            activityService.cacheActivity(convertActivityStatusDTO.getActivityId());
        }

    }

    @Override
    public void rollbackhandlerEvent(ConvertActivityStatusDTO convertActivityStatusDTO) {
        //operatorMap:活动,奖品,人员
        //活动是否需要回滚??绝对需要
        // 原因:都恢复成INIT,那么活动下的奖品绝对没抽完
        for (AbstractActivityOperator operator : operatorMap.values()) {
            operator.convert(convertActivityStatusDTO);
        }

        //缓存更新
        activityService.cacheActivity(convertActivityStatusDTO.getActivityId());

    }

    /**
     * 扭转状态
     *
     * @param convertActivityStatusDTO
     * @param currMap
     * @param sequence
     * @return
     */
    private Boolean processConvertStatus(ConvertActivityStatusDTO convertActivityStatusDTO,
                                         Map<String, AbstractActivityOperator> currMap,
                                         int sequence) {
        Boolean update = false;
        //变量currMap
        Iterator<Map.Entry<String, AbstractActivityOperator>> iterator = currMap.entrySet().iterator();
        while (iterator.hasNext()) {
            AbstractActivityOperator operator = iterator.next().getValue();
            //Operator 是否需要转换
            if (operator.sequence() != sequence || !operator.needConvert(convertActivityStatusDTO)) {
                continue;
            }
            //需要转换：转换
            if (!operator.convert(convertActivityStatusDTO)) {
                log.error("{}状态转化失败!", iterator.getClass().getName());
                throw new ServiceException(ServiceErrorCodeConstants.ACTIVITY_STATUS_CONVERT_ERROR);
            }

            //currMap,删除当前Operator
            iterator.remove(); //不进行删除也可以
            update = true;
        }

        //返回
        return update;
    }
}
